/*  

Cafechess Library: Cover basic chess programming needs, like GUI, Engine integration, 
FEN and PGN parsing.

                 \\|//
                 (o o)
--------------ooO-(_)-Ooo----------------------------------
Copyright (C) 2009  By Gregory A. Prentice Snoqualmie, WA
                    www.cafechess.org
                    cafechess@comcast.net
                      Oooo
--------------oooO----(  )---------------------------------
              (  )    (_/
               \_)

Microsoft Public License (Ms-PL)
               
Revisions:

Author        Date    Description:

*/
using System;
using System.Drawing;
using System.Collections;
using System.Windows.Forms;

using Cafechess.Imaging;
using Cafechess.Chess.Validation;
using Cafechess.Chess.General;
using Cafechess.General.Handle;

namespace Cafechess.Chess.Controls
{
  /// <summary>
  /// This class is responsible for animation of our piece as the mouse
  /// drags it across the board.  It also calls the validation and checks
  /// to make sure the gui may move the piece.
  /// </summary>
	class PieceMoveHelper : IMouseEvents
  {
    public DrawablePiece SourceBitmap;
    PieceLayer OurLayer;
    ChessSurface OurSurface; 
    Point MovePoint;
    Rectangle MovingSquare;
    Rectangle OriginalSquare;
    Cursor coOpenHand;
    Cursor coClosedHand;  
    IValidation coValidation;
    public IValidation Validation
    {
      set
      {
        coValidation = value;
      }
      get
      {
        return coValidation;
      }
    }
    public DrawablePiece SquareClicked
    {
      get{ return coSquareClicked; }
    }
    private DrawablePiece coSquareClicked;

    public PieceMoveHelper(PieceLayer pl)
    {        
      OurLayer = pl;
      OurSurface = (ChessSurface) pl.Parent;
      coOpenHand = new Cursor(GetType(), "Cursors.OpenHand.cur");
      coClosedHand = new Cursor(GetType(), "Cursors.ClosedHand.cur");
      coSquareClicked = null;
    }

    #region IMouseEvents Members
    public void EnterEvent(object sender, EventArgs e)
    {
      OurSurface.Control.Cursor = coOpenHand;
    }
    public void LeaveEvent(object sender, EventArgs e)
    {
      OurSurface.Control.Cursor = Cursors.Default;
    }
    public void HoverEvent(object sender, EventArgs e){}
    /// <summary>
    /// This routine handles the start of our drag and drop operations for
    /// moving our images around on the board.
    /// </summary>
    /// <param name="sender"></param>
    /// <param name="e"></param>
    public void DownEvent(object sender, MouseEventArgs e)
    {
      if(e.Button == MouseButtons.Left )
      {
        bool startDragging = false;
        switch(OurSurface.MoveInput)
        {
          case MoveGeneration.WhiteGUIvsBlackENG:
            startDragging = coValidation.SideToMove;
            break;
          case MoveGeneration.WhiteGUIvsBlackGUI:
            startDragging = true;
            break;
          case MoveGeneration.WhiteENGvsBlackGUI:
            startDragging = !coValidation.SideToMove;
            break;
        }
        // Only if side to move has GUI privilages.
        if( startDragging )
        {
          SourceBitmap = (DrawablePiece)OurLayer.FindSquare(e.X,e.Y);
          if( SourceBitmap != null )
          {
            coSquareClicked = SourceBitmap;
            if(SourceBitmap.Piece != Pieces.None ) //SourceBitmap.Drawing != null )
            {
              OurSurface.Control.Cursor = coClosedHand;
              OurLayer.IsDragging = true;
              SourceBitmap.IsRedraw = false;
              OurLayer.IsRedraw = true;
              OurSurface.IsRedraw = true;
              OurSurface.Render();
              OriginalSquare = SourceBitmap.Square;
              MovingSquare = SourceBitmap.Square;
              MovePoint = new Point(MovingSquare.X + MovingSquare.Width / 2, 
                MovingSquare.Y + MovingSquare.Height / 2);       
              OurSurface.Specialized = OurLayer;
              SourceBitmap.IsRedraw = true;
              OurSurface.Control.Invalidate();
            }
            else
              OurLayer.IsDragging = false;
          }
        }
      }
    }
    public void UpEvent(object sender, MouseEventArgs e)
    {
      if(e.Button == MouseButtons.Left )
      {

        if( OurLayer.IsDragging )
        {
          OurSurface.Control.Cursor = coOpenHand;
          OurLayer.IsDragging = false;
          SourceBitmap.Square = OriginalSquare;
          OurSurface.Specialized = null;
          DrawablePiece TargetBitmap = (DrawablePiece) OurLayer.FindSquare(e.X,e.Y);        
          if( TargetBitmap != null &&
            !TargetBitmap.Name.Equals(SourceBitmap.Name) )
          { 
            SourceBitmap.IsRedraw = true;
            coSquareClicked = TargetBitmap;            
            if( coValidation.Move(SourceBitmap.Piece,SourceBitmap.Name,TargetBitmap.Name) )
            {
              OurLayer.Hide();
            }
          }
          else if( OurSurface.IsEditting && TargetBitmap != SourceBitmap )
          {
            SourceBitmap.Clear();
            SourceBitmap.IsRedraw = true;
            OurLayer.RedrawBoard();
          }
          else
          {
            SourceBitmap.IsRedraw = true;
            OurLayer.RedrawBoard();
          }
        }
      }
    }
    public void MoveEvent(object sender, MouseEventArgs e)
    {
      if( OurLayer.IsDragging )
      {
        int x = e.X - MovePoint.X;
        int y = e.Y - MovePoint.Y;
        MovingSquare.Offset(x, y);
        SourceBitmap.IsRedraw = true;
        SourceBitmap.Square = MovingSquare;

        MovePoint.X = e.X;
        MovePoint.Y = e.Y;
        
        OurSurface.Control.Invalidate(Rectangle.Inflate(MovingSquare,Math.Abs(x*2),Math.Abs(y*2)));
      }
    }
    #endregion
  }


}
